ASP.NET Core Web API 入門心得 - 淺談 non-RESTful 的 Route 覆寫
TLDR
- 透過繼承
BasicController並設定[Route("[controller]/[action]")],可統一管理 API 路由,減少重複設定。 - Controller 層級的
[Route]會直接覆寫BasicController的預設路由。 - Action 層級的
[Route]預設會與 Controller 的路由進行串接。 - 若 Action 需要完全取代 Controller 的路由設定,需在
[Route]字串開頭加上/或~前綴。 - 若僅需修改 Action 的 URL 名稱,建議使用
[ActionName]屬性。
在 non-RESTful 風格的 Web API 開發中,為了簡化維護,通常會透過繼承 BasicController 來統一路由定義。
統一路由設定
什麼情況下會遇到這個問題:當專案規範採用 Controller/Action 格式,且希望避免在每個 Controller 中重複撰寫路由屬性時。
透過定義抽象類別 BasicController,可以將路由規則集中管理:
csharp
[ApiController]
[Route("[controller]/[action]")]
public abstract class BasicController : ControllerBase {
}
public class TestRouteController : BasicController {
// URL: /TestRoute/TestAction
[HttpPost]
public void TestAction() {
}
}路由覆寫與串接規則
什麼情況下會遇到這個問題:當現有 API 路徑與預設規則不符,需要針對特定 Controller 或 Action 進行路徑調整時。
在 ASP.NET Core 中,[Route] 的行為取決於其放置的位置以及是否包含特殊前綴:
- Controller 覆寫:在 Controller 上使用
[Route]會直接取代BasicController的設定。 - Action 串接:若在 Action 上使用
[Route],預設會與 Controller 的路由進行串接,容易導致路徑過長。 - 完全覆寫 (絕對路徑):在 Action 的
[Route]字串開頭加上/或~,可忽略 Controller 的路由設定。
以下為不同情境的實作範例:
csharp
[ApiController]
[Route("[controller]/[action]")]
public abstract class BasicController : ControllerBase {
}
[Route("Override/[action]")]
public class TestRouteController : BasicController {
// 情境:Controller 覆寫 Route,Action 不處理
// URL:/Override/OverrideController
[HttpPost]
public void OverrideController() {
}
// 常見誤用情境:Controller 和 Action 都覆寫 Route,導致 Action 的 URL 是兩者 Route 的串接
// URL:/Override/OverrideAction/Action/OverrideAction
[HttpPost]
[Route("Action/[action]")]
public void OverrideAction() {
}
// 情境:Action 不想使用 Controller 設定的 Route,在 Route 最前面加上 "/"
// URL:/Action/OnlyAction
[HttpPost]
[Route("/Action/[action]")]
public void OnlyAction() {
}
// 情境:Action 不想使用 Controller 設定的 Route,在 Route 最前面加上 "~",效果同上
// URL:/Action/OnlyAction2
[HttpPost]
[Route("~/Action/[action]")]
public void OnlyAction2() {
}
// 情境:單純只想要修改 Action 名稱
// URL:/Override/Rename
[HttpPost]
[ActionName("Rename")]
public void RenameAction() {
}
}結論
針對 non-RESTful 架構,建議優先使用 BasicController 進行全域路由規範。若需針對個別 Action 調整路徑,應優先評估是否僅需修改名稱(使用 [ActionName]),若需完全變更路徑結構,則務必使用 / 或 ~ 前綴以避免不必要的路由串接。
異動歷程
- 初版文件建立。